package com.way.capture.core;

import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.Intent;
import android.media.projection.MediaProjectionManager;
import android.net.Uri;
import android.os.Bundle;
import android.provider.Settings;
import androidx.appcompat.app.AppCompatActivity;
import android.util.Log;
import android.widget.Toast;

import com.tbruyelle.rxpermissions2.RxPermissions;
import com.way.capture.R;
import com.way.capture.service.ShakeService;
import com.way.capture.utils.OsUtil;
import com.way.capture.utils.Utils;

import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;

public class LauncherActivity extends AppCompatActivity {
    private static final String TAG = "LauncherActivity";
    private static final int REQUEST_CODE_OVERLAYS = 99;
    private static final int REQUEST_CODE_SCREENSHOT = 100;
    private Disposable mDisposable;
    private boolean mHasShow;
    private boolean mIsRequestOverlays;
    private String mAction;

    public static void startCaptureActivity(Context context, String action) {
        Intent intent = new Intent(context, LauncherActivity.class);
        intent.setAction(action);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
        context.startActivity(intent);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getIntent() == null || getIntent().getAction() == null) {
            finish();
            return;
        }
        mIsRequestOverlays = false;
        mAction = getIntent().getAction();
        if (ShakeService.Action.ACTION_RECORD.equals(mAction)
                && com.way.capture.utils.Settings.getInstance().isVideoAudio()) {
            ensurePermission();
            return;
        } else if (ShakeService.Action.ACTION_REQUEST_DRAW_OVERLAYS.equals(mAction)) {
            requestAlertWindowPermission();
            return;
        }
        requestScreenshotPermission();
    }

    private void requestAlertWindowPermission() {
        new AlertDialog.Builder(this).setTitle(R.string.permission_title)
                .setCancelable(false)
                .setMessage(R.string.required_permissions_overlay)
                .setNegativeButton(android.R.string.cancel, (dialog, which) -> finish())
                .setPositiveButton(android.R.string.ok, (dialog, which) -> {
                    Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
                    intent.setData(Uri.parse(Utils.PACKAGE_URI_PREFIX + getPackageName()));
                    startActivityForResult(intent, REQUEST_CODE_OVERLAYS);
                    mIsRequestOverlays = true;
                }).show();
    }

    private void ensurePermission() {
        if (mDisposable != null && !mDisposable.isDisposed()) {
            mDisposable.dispose();
        }
        mDisposable = new RxPermissions(this).requestEach(Manifest.permission.RECORD_AUDIO)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(permission -> {
                    if (permission.granted) {
                        requestScreenshotPermission();
                    } else if (permission.shouldShowRequestPermissionRationale) {
                        if (mHasShow) {
                            finish();
                        } else {
                            showRequestPermissionDialog();
                        }
                    } else {
                        gotoSettings();
                    }
                }, throwable -> {
                    Log.e(TAG, "ensureAudioPermission: ", throwable);
                    finish();
                });
    }

    private void requestScreenshotPermission() {
        try {
            MediaProjectionManager manager = (MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE);
            Intent intent = manager.createScreenCaptureIntent();
            startActivityForResult(intent, REQUEST_CODE_SCREENSHOT);
            Log.i(TAG, "fireScreenCaptureIntent...");
        } catch (Exception e) {
            Toast.makeText(this, R.string.not_support_devices, Toast.LENGTH_SHORT).show();
            finish();
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode) {
            case REQUEST_CODE_OVERLAYS:
                if (OsUtil.canDrawOverlays(this)) {
                    Log.d(TAG, "Acquired permission to show overlay. resultCode = " + resultCode);
                    final Intent notifyIntent = new Intent(this, ShakeService.class);
                    notifyIntent.setAction(ShakeService.Action.ACTION_SHOW_MENU);
                    startService(notifyIntent);
                } else {
                    Log.d(TAG, "Failed to acquire permission to show overlay.");
                }
                break;
            case REQUEST_CODE_SCREENSHOT:
                if (resultCode == Activity.RESULT_OK) {
                    Log.d(TAG, "Acquired permission to screen capture. Starting service.");
                    startService(ShakeService.newIntent(this, mAction, resultCode, data));
                } else {
                    Log.d(TAG, "Failed to acquire permission to screen capture.");
                }
                break;
            default:
                break;
        }
        finish();
    }

    @Override
    protected void onStop() {
        if (!mIsRequestOverlays && !isFinishing()) {
            finish();
        }
        super.onStop();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mDisposable != null && !mDisposable.isDisposed()) {
            mDisposable.dispose();
        }
    }

    private void showRequestPermissionDialog() {
        new AlertDialog.Builder(this).setTitle(R.string.permission_title)
                .setCancelable(false)
                .setMessage(R.string.required_permissions_audio)
                .setNegativeButton(android.R.string.cancel, (dialog, which) -> finish())
                .setPositiveButton(android.R.string.ok, (dialog, which) -> {
                    ensurePermission();
                }).show();
        mHasShow = true;
    }

    private void gotoSettings() {
        new AlertDialog.Builder(this).setTitle(R.string.permission_title)
                .setCancelable(false)
                .setMessage(R.string.enable_permission_procedure)
                .setNegativeButton(android.R.string.cancel, (dialog, which) -> finish())
                .setPositiveButton(android.R.string.ok, (dialog, which) -> {
                    final Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
                            Uri.parse(Utils.PACKAGE_URI_PREFIX + getPackageName()));
                    startActivity(intent);
                }).show();
    }
}
